package com.health.ts.service.scheduling;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.health.ts.dao.register.SourceMapper;
import com.health.ts.dao.scheduling.SchedulingMapper;
import com.health.ts.dao.sysmanage.SysDepartmentMapper;
import com.health.ts.dao.sysmanage.SysDeviceMapper;
import com.health.ts.dao.sysmanage.SysUserMapper;
import com.health.ts.entity.register.Source;
import com.health.ts.entity.scheduling.Scheduling;
import com.health.ts.entity.sysmanage.SysDepartment;
import com.health.ts.entity.sysmanage.SysDevice;
import com.health.ts.entity.sysmanage.SysUser;
import com.health.ts.exception.BusinessException;
import com.health.ts.utils.DateUtil;
import com.health.ts.utils.GenerateIdUtil;
import com.health.ts.utils.SessionUserUtil;
@Service
public class SchedulingService extends ServiceImpl<SchedulingMapper, Scheduling>{
	
	@Autowired
	SourceMapper sourceMapper;
	
	@Autowired
	SysDepartmentMapper sysDepartmentMapper;
	
	@Autowired
	SysUserMapper sysUserMapper;
	
	@Autowired
	SysDeviceMapper sysDeviceMapper;
	
	//用户报告角色
	private static final String USER_ROLE_REPORT="role_report";
	
	/**
	 * 新增排班
	 * @param scheduling
	 */
	@Transactional(rollbackFor = Exception.class)
	public String addScheduling(Scheduling scheduling) {
		scheduling.setId(GenerateIdUtil.makeID());
		scheduling.setSchedu_hid(SessionUserUtil.getUserHosId());
		scheduling.setCreate_time(new Date());
		scheduling.setUpdate_time(new Date());
		scheduling.setOperator_id(SessionUserUtil.getUserId());
		scheduling.setOperator_name(SessionUserUtil.getUserName());
		boolean isSucess=false;
		if(checkScheduling(scheduling)){
			isSucess=this.save(scheduling);
		}else{
			throw new BusinessException("排班区间有交叉，处理失败！");
		}
		if(isSucess){
			for(int i=1;i<=scheduling.getSchedu_num();i++){
				Source source=new Source();
				source.setId(GenerateIdUtil.makeID());
				source.setDocid(scheduling.getDoc_id());
				source.setDepartment_id(scheduling.getSchedu_did());
				source.setHospital_id(SessionUserUtil.getUserHosId());
				source.setOrder(i);
				source.setHy_timetype(scheduling.getSchedu_noon());
				source.setPbid(scheduling.getId());
				source.setIs_used("0");
				source.setUse_time(scheduling.getSchedu_date());
				sourceMapper.insert(source);
			}
		}
		return scheduling.getId();
	}
	
	/**
	 * 排班校验
	 * @param scheduling
	 * @return
	 */
	private boolean checkScheduling(Scheduling scheduling){
		boolean checkResult=false;
		QueryWrapper<Scheduling> checkWrapper = new QueryWrapper<Scheduling>();
		checkWrapper.eq("schedu_type", scheduling.getSchedu_type());
		checkWrapper.eq("schedu_hid", scheduling.getSchedu_hid());
		checkWrapper.eq("schedu_did", scheduling.getSchedu_did());
		if("1".equals(scheduling.getSchedu_type())){
			checkWrapper.eq("device_id", scheduling.getDevice_id());
		}else{
			checkWrapper.eq("doc_id", scheduling.getDoc_id());
		}
		
		if(StringUtils.isNotEmpty(scheduling.getId())){
			checkWrapper.ne("id", scheduling.getId());
		}
		
		checkWrapper.eq("schedu_date", DateUtil.forDate(scheduling.getSchedu_date(),DateUtil.FORMAT_DATE));
		
		List<Scheduling> checkList = this.list(checkWrapper);
		if(checkList.isEmpty()){
			checkResult = true;
		}else{
			long inputStart = getScheduDateTime(scheduling.getSchedu_date(),scheduling.getSchedu_start());
			long inputEnd = getScheduDateTime(scheduling.getSchedu_date(),scheduling.getSchedu_end());
			for(Scheduling exsit : checkList){
				long exsitStart = getScheduDateTime(exsit.getSchedu_date(),exsit.getSchedu_start());
				long exsitEnd = getScheduDateTime(exsit.getSchedu_date(),exsit.getSchedu_end());
				if(inputStart >= exsitEnd || inputEnd <= exsitStart){
					checkResult = true;
				}else{
					checkResult = false;
					break;
				}
			}
		}
		return checkResult;
	}
	
	private long getScheduDateTime(Date ScheduDate,String hourTime){
		String dateStr = DateUtil.forDate(ScheduDate,DateUtil.FORMAT_DATE);
		String dateTimeStr= dateStr+" "+hourTime+":00";
		return DateUtil.parseDate(dateTimeStr).getTime();
	}
	/**
	 * 删除排班
	 * @param scheduling
	 */
	@Transactional
	public void deleteScheduling(String scheduId){
		//删除排班
		this.baseMapper.deleteById(scheduId);
		//删除号源
		QueryWrapper<Source> deleteSourceWrapper = new QueryWrapper<Source>();
		deleteSourceWrapper.eq("pbid", scheduId);
		sourceMapper.delete(deleteSourceWrapper);
	}
	
	/**
	 * 更新排班
	 * @param scheduId
	 * @param scheduling
	 * @throws Exception 
	 */
	@Transactional(rollbackFor = Exception.class)
	public void updateScheduling(String scheduId,Scheduling scheduling){
		if(this.baseMapper.selectById(scheduId)!=null){
			scheduling.setId(scheduId);
			scheduling.setUpdate_time(new Date());
			scheduling.setOperator_id(SessionUserUtil.getUserId());
			scheduling.setOperator_name(SessionUserUtil.getUserName());
			
			boolean isSucess=false;
			if(checkScheduling(scheduling)){
				//更新排班
				isSucess=this.updateById(scheduling);
			}else{
				throw new BusinessException("排班区间有交叉，处理失败！");
			}
			
			if(isSucess){
				//更新排班成功后，删除之前的号源
				QueryWrapper<Source> wrapper = new QueryWrapper<Source>();
				wrapper.eq("pbid", scheduId); 
				sourceMapper.delete(wrapper);
				//重新插入号源
				for(int i=1;i<=scheduling.getSchedu_num();i++){
					Source source=new Source();
					source.setId(GenerateIdUtil.makeID());
					source.setDocid(scheduling.getDoc_id());
					source.setDepartment_id(scheduling.getSchedu_did());
					source.setHospital_id(SessionUserUtil.getUserHosId());
					source.setOrder(i);
					source.setHy_timetype(scheduling.getSchedu_noon());
					source.setPbid(scheduId);
					source.setIs_used("0");
					source.setUse_time(scheduling.getSchedu_date());
					sourceMapper.insert(source);
				}
			}
		}
	}
	
	/**
	 * 查询单个排班
	 * @param scheduId
	 */
	public Scheduling getScheduling(String scheduId){
		return this.baseMapper.selectById(scheduId);
	}
	
	/**
	 * 查询排班科室
	 */
	public List<SysDepartment>  getScheduDepts(){
		QueryWrapper<SysDepartment> wrapper = new QueryWrapper<SysDepartment>();
		wrapper.eq("hospital_id", SessionUserUtil.getUserHosId());
		
		wrapper.orderByAsc("update_time");
		return sysDepartmentMapper.selectList(wrapper);
	}
	
	/**
	 * 查询排班医生
	 */
	public List<SysUser>  getScheduDoctors(String department_id){
		QueryWrapper<SysUser> wrapper = new QueryWrapper<SysUser>();
		if(StringUtils.isNotEmpty(department_id)){
			wrapper.eq("department_id", department_id);
		}
		
		//返回结果需要用户角色列表包含报告角色的用户
		wrapper.like("role_id", USER_ROLE_REPORT);
		
		wrapper.orderByDesc("update_time");
		return sysUserMapper.selectList(wrapper);
	}
	
	/**
	 * 查询排班设备
	 */
	public List<SysDevice>  getScheduDevices(String department_id){
		QueryWrapper<SysDevice> wrapper = new QueryWrapper<SysDevice>();
		if(StringUtils.isNotEmpty(department_id)){
			wrapper.eq("department_id", department_id);
		}
		wrapper.orderByDesc("update_time");
		return sysDeviceMapper.selectList(wrapper);
	}
}
